/**
 * 
 */
package view;

import static com.google.common.base.Preconditions.checkNotNull;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import model.HeatMap;
import net.sf.javaml.clustering.KMeans;
import tools.HeatMapPreview;

import com.alee.laf.StyleConstants;
import com.alee.laf.button.WebButton;
import com.alee.laf.checkbox.WebCheckBox;
import com.alee.laf.filechooser.WebFileChooser;
import com.alee.laf.label.WebLabel;
import com.alee.laf.panel.WebPanel;
import com.alee.laf.scroll.WebScrollPane;
import com.alee.laf.text.WebTextArea;
import com.alee.laf.text.WebTextField;
import com.alee.utils.FileUtils;
import com.alee.utils.ImageUtils;

import controller.Controls;

/**
 * @author Jamada
 */
public class HeatMapPanel extends JPanel {
	private static final Logger logger = LoggerFactory.getLogger(HeatMapPanel.class);
    /**
     * Serial Version ID.
     */
    private static final long serialVersionUID = 1588094984504349688L;    
    
    private static final String SAMPLE_HEAT_MAP_IMAGE_FILE = "InitialHeatMapSample.png";
    
    private static final String GRADIENT_HEAT_MAP_IMAGE_FILE = "heat_map_key.png";
    //Button Names
    private static final String GEN_HEAT_MAP_DATA = "Generate Heat Map Data";
    private static final String LOW_COLOR = "Low Color";
    private static final String HIGH_COLOR = "High Color";
    private static final String UPDATE_PREVIEW = "Update Preview";
    
    //K Means Field Names
    private static final String CLUSTER_FIELD_PRO = "Clusters";
    private static final String ITERATIONS_FIELD_PRO = "Iterations";
    private static final String CHECKBOX_PRO = "Cluster by proteins";
    private static final String CLUSTER_FIELD_COMP = "Clusters_compound";
    private static final String ITERATIONS_FIELD_COMP = "Iterations_compound";
    private static final String CHECKBOX_COMP = "Cluster by compounds";
    
    private final Controls controls;
    
    private final HeatMap sampleHeatMap;
    
    private final HeatMap gradientHeatMap;
    
    private String defaultQueryProteins;
    
    private String defaultQueryCompounds;
    
    private String defaultNumClusters;
    
    private String defaultNumIterations;
    
    private WebPanel sampleHeatMapPanel;
    
    private WebTextArea compoundTextArea;
    
    private WebTextArea proteinTextArea;
    
    private JLabel sampleHeatMapImageLabel;
    
    private JLabel gradientHeatMapImageLabel;
    
    private Color heatMapLowColor;
    
    private Color heatMapHighColor;
    
    //private WebCheckBox kMeansCheckBox;
    Map<String, WebCheckBox> kMeansCheckBoxes;
    
    Map<String, WebTextField> kMeansTextFields;
    
    private Map<String, WebButton> buttonMap;
    
    
    public HeatMapPanel(Controls controls) {
    	loadProperties();
        this.controls = controls;
        this.sampleHeatMap = new HeatMap(HeatMapPreview.getSampleHeatMapData());
        this.gradientHeatMap = new HeatMap(HeatMapPreview.getGradientHeatMapData());
        this.setLayout(new BorderLayout());
        this.setBackground(Color.WHITE);
        this. buttonMap = createButtonMap();
        buildMainPanel();
    }
    
    /**
     * Builds main heat map panel.
     */
    private void buildMainPanel() {
        JPanel masterPanel = new JPanel();
        masterPanel.setLayout(new BoxLayout(masterPanel, BoxLayout.PAGE_AXIS));
        masterPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
        
        //Labels
        WebLabel titleLabel = new WebLabel("Heat Map Generator");
        titleLabel.setFontSize(16);
        
        WebLabel sampleLabel = new WebLabel("Preview");
        sampleLabel.setFontSize(12);
        sampleLabel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
        
        WebLabel queryLabel = new WebLabel("Query");
        queryLabel.setFontSize(14);
        queryLabel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
        
        //Panels
        JPanel labelPanel = new JPanel();
        labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
        labelPanel.add(titleLabel);
        labelPanel.add(sampleLabel);
        
        this.sampleHeatMapPanel = buildSamplePanel();
        JPanel queryPanel = buildQueryPanel();
        JPanel kMeansPanel = buildKMeansPanel();
        
        //Alignment
        labelPanel.setAlignmentX(CENTER_ALIGNMENT);
        titleLabel.setAlignmentX(CENTER_ALIGNMENT);
        sampleLabel.setAlignmentX(CENTER_ALIGNMENT);
        queryLabel.setAlignmentX(CENTER_ALIGNMENT);
        kMeansPanel.setAlignmentX(CENTER_ALIGNMENT);
        this.sampleHeatMapPanel.setAlignmentX(CENTER_ALIGNMENT);
        queryPanel.setAlignmentX(CENTER_ALIGNMENT);
        
        //Opacity
        labelPanel.setOpaque(false);
        sampleLabel.setOpaque(false);
        titleLabel.setOpaque(false);
        this.sampleHeatMapPanel.setOpaque(false);
        queryPanel.setOpaque(false);
        queryLabel.setOpaque(false);
        kMeansPanel.setOpaque(false);
        masterPanel.setOpaque(false);
      
        //Final Setup
        masterPanel.add(this.sampleHeatMapPanel);
        masterPanel.add(queryLabel);
        masterPanel.add(queryPanel);
        masterPanel.add(kMeansPanel);
        masterPanel.add(this.buttonMap.get(GEN_HEAT_MAP_DATA));

        this.add(labelPanel, BorderLayout.NORTH);
        this.add(masterPanel, BorderLayout.CENTER);

    }
    
    public String getCompoundTextString() {
    	return this.compoundTextArea.getText();
    }
    
    public String getProteinTextString() {
    	return this.proteinTextArea.getText();
    }
    
    private WebPanel buildSamplePanel() {
        final WebPanel result = new WebPanel();
        result.setUndecorated ( false );
        result.setMargin ( 20 );
        result.setRound ( StyleConstants.largeRound );
        result.getWebUI().setPaintBackground(false);
        result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));
        
        //Panels
        JPanel picturePanel = new JPanel();
        picturePanel.setLayout(new BoxLayout(picturePanel, BoxLayout.LINE_AXIS));
        JPanel colorButtonPanel = new JPanel();
        colorButtonPanel.setLayout(new BoxLayout(colorButtonPanel, BoxLayout.LINE_AXIS));
        
        //Labels 
        BufferedImage samplePicture = checkNotNull(getImageFromFile(SAMPLE_HEAT_MAP_IMAGE_FILE));
        this.sampleHeatMapImageLabel = new JLabel(new ImageIcon(samplePicture));
        this.sampleHeatMapImageLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
        
        BufferedImage heatMapKey = checkNotNull(getImageFromFile(GRADIENT_HEAT_MAP_IMAGE_FILE));
        this.gradientHeatMapImageLabel  = new JLabel(new ImageIcon(heatMapKey));
        this.gradientHeatMapImageLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 45));
        
        //Alignment
        picturePanel.setAlignmentX(CENTER_ALIGNMENT);
        this.sampleHeatMapImageLabel.setAlignmentX(CENTER_ALIGNMENT);
        this.gradientHeatMapImageLabel.setAlignmentX(CENTER_ALIGNMENT);
        
        //Opacity
        picturePanel.setOpaque(false);
        colorButtonPanel.setOpaque(false);
        
        //final setup
        picturePanel.add(sampleHeatMapImageLabel);
        picturePanel.add(gradientHeatMapImageLabel);
        colorButtonPanel.add(this.buttonMap.get(LOW_COLOR));
        colorButtonPanel.add(this.buttonMap.get(HIGH_COLOR));
        result.add(picturePanel);
        result.add(colorButtonPanel);
        result.add(this.buttonMap.get(UPDATE_PREVIEW));
        
        return result;
    }
    
    private JPanel buildQueryPanel() {
    	JPanel masterQueryPanel = new JPanel();
    	masterQueryPanel.setLayout(new BoxLayout(masterQueryPanel, BoxLayout.LINE_AXIS));
    	masterQueryPanel.setOpaque(false);
    	masterQueryPanel.setAlignmentX(CENTER_ALIGNMENT);
    	
    	//Compound Panel
        JPanel compoundPanel = new JPanel();
        compoundPanel.setLayout(new BoxLayout(compoundPanel, BoxLayout.PAGE_AXIS));
        
        WebLabel compoundLabel = new WebLabel("Drug Compounds");
        
        this.compoundTextArea = new WebTextArea ();
        this.compoundTextArea.setText(this.defaultQueryCompounds);
        this.compoundTextArea.setToolTipText("Empty text area queries every compound.");
        this.compoundTextArea.setLineWrap ( true );
        this.compoundTextArea.setWrapStyleWord ( true );

        WebScrollPane compoundAreaScroll = new WebScrollPane ( this.compoundTextArea );
        compoundAreaScroll.setPreferredSize(new Dimension(150, 150));
        compoundAreaScroll.setMaximumSize ( new Dimension ( 250, 150 ) );
           
        //Protein Panel
        JPanel proteinPanel = new JPanel();
        proteinPanel.setLayout(new BoxLayout(proteinPanel, BoxLayout.PAGE_AXIS));
        
        WebLabel proteinLabel = new WebLabel("Proteins <UniProt IDs>");
        
        this.proteinTextArea = new WebTextArea ();
        this.proteinTextArea.setText(this.defaultQueryProteins);
        this.proteinTextArea.setToolTipText("Empty text area queries every protein.");
        this.proteinTextArea.setLineWrap ( true );
        this.proteinTextArea.setWrapStyleWord ( true );

        WebScrollPane proteinAreaScroll = new WebScrollPane ( this.proteinTextArea );
        proteinAreaScroll.setPreferredSize(new Dimension(150, 150));
        proteinAreaScroll.setMaximumSize ( new Dimension ( 250, 150 ) );
        
        //Opacity
        proteinLabel.setOpaque(false);
        proteinPanel.setOpaque(false);
        compoundLabel.setOpaque(false);
        compoundPanel.setOpaque(false);
        
        //Alignment
        proteinLabel.setAlignmentX(CENTER_ALIGNMENT);
        this.proteinTextArea.setAlignmentX(CENTER_ALIGNMENT);
        compoundLabel.setAlignmentX(CENTER_ALIGNMENT);
        this.compoundTextArea.setAlignmentX(CENTER_ALIGNMENT);
                
        //Construction
        compoundPanel.add(compoundLabel);
        compoundPanel.add(compoundAreaScroll);
        compoundPanel.add(createFileChooserButton("load compounds from csv...", this.compoundTextArea));
        
        proteinPanel.add(proteinLabel);
        proteinPanel.add(proteinAreaScroll);
        proteinPanel.add(createFileChooserButton("load proteins from csv...", this.proteinTextArea));
        
        masterQueryPanel.add(compoundPanel);
        masterQueryPanel.add(proteinPanel);
        
        return masterQueryPanel;
    }
    
    private JPanel kMeansInputPanel(final String title, final int number) {
    	JPanel kMeansPanel = new JPanel();
    	kMeansPanel.setLayout(new BoxLayout(kMeansPanel, BoxLayout.LINE_AXIS));
    	kMeansPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 20, 0));
    	
    	//Panels
    	JPanel clusterPanel = new JPanel();
    	clusterPanel.setLayout(new BoxLayout(clusterPanel, BoxLayout.PAGE_AXIS));
    	
    	JPanel iterationsPanel = new JPanel();
    	iterationsPanel.setLayout(new BoxLayout(iterationsPanel, BoxLayout.PAGE_AXIS));
    	
    	//Labels
    	WebLabel clusterLabel = new WebLabel("Clusters");
    	WebLabel iterationsLabel = new WebLabel("Iterations");
    	clusterLabel.setMargin(0, 10, 0, 10);

    	//TextFields
    	final WebTextField clusterField = new WebTextField(this.defaultNumClusters);
    	final WebTextField iterationsField = new WebTextField(this.defaultNumIterations);
    	clusterField.setMaximumSize(new Dimension(50, 24));
    	iterationsField.setMaximumSize(new Dimension(75, 24));


    	//Checkbox
    	final WebCheckBox kMeansCheckBox = new WebCheckBox(title);
    	kMeansCheckBox.setSelected(true);

    	//Opacity
    	clusterPanel.setOpaque(false);
    	iterationsPanel.setOpaque(false);
    	kMeansPanel.setOpaque(false);
    	
    	//Alignment
    	clusterPanel.setAlignmentX(CENTER_ALIGNMENT);
    	clusterLabel.setAlignmentX(CENTER_ALIGNMENT);
    	clusterField.setAlignmentX(CENTER_ALIGNMENT);
    	iterationsPanel.setAlignmentX(CENTER_ALIGNMENT);
    	iterationsLabel.setAlignmentX(CENTER_ALIGNMENT);
    	iterationsField.setAlignmentX(CENTER_ALIGNMENT);
    	kMeansCheckBox.setAlignmentX(CENTER_ALIGNMENT);
    	
    	//construction
    	clusterPanel.add(clusterLabel);
    	clusterPanel.add(clusterField);
    	iterationsPanel.add(iterationsLabel);
    	iterationsPanel.add(iterationsField);
    	kMeansPanel.add(kMeansCheckBox);
    	kMeansPanel.add(clusterPanel);
    	kMeansPanel.add(iterationsPanel);
    	
    	if (number == 1) {
    		this.kMeansTextFields.put(CLUSTER_FIELD_PRO, clusterField);
    		this.kMeansTextFields.put(ITERATIONS_FIELD_PRO, iterationsField);
    		this.kMeansCheckBoxes.put(CHECKBOX_PRO, kMeansCheckBox);
    	} else {
    		this.kMeansTextFields.put(CLUSTER_FIELD_COMP, clusterField);
    		this.kMeansTextFields.put(ITERATIONS_FIELD_COMP, iterationsField);
    		this.kMeansCheckBoxes.put(CHECKBOX_COMP, kMeansCheckBox);
    	}
    	  	
    	return kMeansPanel;
    }
    
    private JPanel buildKMeansPanel() {
    	this.kMeansTextFields = new HashMap<String, WebTextField>();
    	this.kMeansCheckBoxes = new HashMap<String, WebCheckBox>();
    	
    	JPanel masterKMeansPanel = new JPanel();
    	masterKMeansPanel.setLayout(new BoxLayout(masterKMeansPanel, BoxLayout.PAGE_AXIS));
    	
    	//Labels
    	WebLabel titleLabel = new WebLabel("K-Means Clustering");
    	titleLabel.setMargin(10, 0, 0, 0);
    	
    	//Opacity
    	masterKMeansPanel.setOpaque(false);
    	
    	//Alignment
    	titleLabel.setAlignmentX(CENTER_ALIGNMENT); 
    	
    	//Final Construction
    	masterKMeansPanel.add(titleLabel);
    	masterKMeansPanel.add(kMeansInputPanel(CHECKBOX_PRO, 1));
    	masterKMeansPanel.add(kMeansInputPanel(CHECKBOX_COMP, 2));
    	return masterKMeansPanel;
    }
    
    private Map<String, WebButton> createButtonMap() {
    	Map<String, WebButton> buttonMapResult = new HashMap<String, WebButton>();
    	
    	//Generate Heat Map Button
        WebButton genHeatMapButton = new WebButton(GEN_HEAT_MAP_DATA);
        genHeatMapButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent the_event) {
            	buttonMap.get(GEN_HEAT_MAP_DATA).setEnabled(false);
            	controls.displayProgressBar();
//    			KMeans kMeansPro = null;
//    			KMeans kMeansComp = null;
//    			if (kMeansCheckBoxes.get(CHECKBOX_PRO).isSelected()) {
//    				final int numClusters = Integer.parseInt(kMeansTextFields.get(CLUSTER_FIELD_PRO).getText());
//    				final int numIterations = Integer.parseInt(kMeansTextFields.get(ITERATIONS_FIELD_PRO).getText());
//    				kMeansPro = new KMeans(numClusters, numIterations);
//    			}
//    			if (kMeansCheckBoxes.get(CHECKBOX_COMP).isSelected()) {
//    				final int numClusters = Integer.parseInt(kMeansTextFields.get(CLUSTER_FIELD_COMP).getText());
//    				final int numIterations = Integer.parseInt(kMeansTextFields.get(ITERATIONS_FIELD_COMP).getText());
//    				kMeansComp = new KMeans(numClusters, numIterations);
//    			}
//
//    			controls.generateHeatMap(getCompoundText(), getProteinText(), kMeansPro, kMeansComp);
            	new ClusteringHandler().execute();
//            	if (kMeansCheckBox.isSelected()) {
//            		controls.generateHeatMap(getCompoundText(), getProteinText(), new KMeans(getNumClusters(), getNumIterations()));
//            	} else {
//            		controls.generateHeatMap(getCompoundText(), getProteinText());
//            	} 
            }
        });
        //Low Color Button
        final WebButton lowColorButton = new WebButton(LOW_COLOR, ImageUtils.createColorIcon(this.heatMapLowColor));
        lowColorButton.setMargin(0, 0, 0, 3);
		lowColorButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {

				final Color colorResult = JColorChooser.showDialog(sampleHeatMapPanel, "Heat Map Color", heatMapLowColor);
				if (colorResult != null) {
					heatMapLowColor = colorResult;
					lowColorButton.setIcon(ImageUtils.createColorIcon(heatMapLowColor));
				}
			}
		});  
		//High Color Button
        final WebButton highColorButton = new WebButton(HIGH_COLOR, ImageUtils.createColorIcon(this.heatMapHighColor));
        highColorButton.setMargin(0, 0, 0, 0);
		highColorButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				final Color colorResult = JColorChooser.showDialog(sampleHeatMapPanel, "Heat Map Color", heatMapHighColor);
				if (colorResult != null) {
					heatMapHighColor = colorResult;
					highColorButton.setIcon(ImageUtils.createColorIcon(heatMapHighColor));
				}
			}
		});
		//Update images of heat map preview
		final WebButton updatePreviewButton = new WebButton(UPDATE_PREVIEW);
		updatePreviewButton.setRound(9);
		updatePreviewButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
                sampleHeatMap.setLowColor(heatMapLowColor);
                sampleHeatMap.setHighColor(heatMapHighColor);
                sampleHeatMap.saveImageToFile(SAMPLE_HEAT_MAP_IMAGE_FILE);
                
                gradientHeatMap.setLowColor(heatMapLowColor);
                gradientHeatMap.setHighColor(heatMapHighColor);
                gradientHeatMap.saveImageToFile(GRADIENT_HEAT_MAP_IMAGE_FILE);
                
                BufferedImage samplePicture = checkNotNull(getImageFromFile(SAMPLE_HEAT_MAP_IMAGE_FILE));
                sampleHeatMapImageLabel.setIcon(new ImageIcon(samplePicture));
                
                BufferedImage heatMapKey = checkNotNull(getImageFromFile(GRADIENT_HEAT_MAP_IMAGE_FILE));
                gradientHeatMapImageLabel.setIcon(new ImageIcon(heatMapKey));
                
                controls.setDefaultColors(heatMapLowColor, heatMapHighColor);
                controls.updateView();
                
			}
		});
        
		//Alignment
        genHeatMapButton.setAlignmentX(CENTER_ALIGNMENT);
        lowColorButton.setAlignmentX(CENTER_ALIGNMENT);
        highColorButton.setAlignmentX(CENTER_ALIGNMENT);
        updatePreviewButton.setAlignmentX(CENTER_ALIGNMENT);
    	
        //Set map
        buttonMapResult.put(GEN_HEAT_MAP_DATA, genHeatMapButton);
        buttonMapResult.put(LOW_COLOR, lowColorButton);
        buttonMapResult.put(HIGH_COLOR, highColorButton);
        buttonMapResult.put(UPDATE_PREVIEW, updatePreviewButton);
    	
    	return buttonMapResult;
    }
    
    private WebButton createFileChooserButton(final String name, final WebTextArea textArea) {
    	//csv files only
        final WebButton fileChooserButton = new WebButton (name);
        fileChooserButton.setAlignmentX(CENTER_ALIGNMENT);
        fileChooserButton.addActionListener ( new ActionListener () {
            private WebFileChooser csvChooser = null;
            private File file = null;
            final FileNameExtensionFilter csvFilter = new FileNameExtensionFilter("CSV Only", "csv"); 

            @Override
			public void actionPerformed(ActionEvent e) {
				if (csvChooser == null) {
					csvChooser = new WebFileChooser();
					csvChooser.setMultiSelectionEnabled(false);
					csvChooser.setAcceptAllFileFilterUsed(false);
					
					csvChooser.setFileFilter(csvFilter);
				}
				if (file != null) {
					csvChooser.setSelectedFile(file);
				}
				if (csvChooser.showOpenDialog(sampleHeatMapPanel) == WebFileChooser.APPROVE_OPTION) {
					file = csvChooser.getSelectedFile();
					fileChooserButton.setIcon(FileUtils.getFileIcon(file));
					fileChooserButton.setText(FileUtils
							.getDisplayFileName(file));
					BufferedReader bReader;
					try {
						bReader = new BufferedReader(new FileReader(file));

						String line;
						final StringBuilder sb = new StringBuilder();
						while ((line = bReader.readLine()) != null) {
							sb.append(line);
							sb.append(", ");
						}
						sb.deleteCharAt(sb.lastIndexOf(","));
						bReader.close();
						textArea.setText(sb.toString());
					} catch (FileNotFoundException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
        return fileChooserButton;
    }
    
    private BufferedImage getImageFromFile(String fileLocation) {
        BufferedImage result = null;
        try {
            result = ImageIO.read(new File(fileLocation));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    
    public String[] getProteinText() {
    	String[] result = this.proteinTextArea.getText().split("\\s*,\\s*");
    	if (result != null && result.length == 1 && result[0].equals("")) {
    		result = null;
    	}
    	return result;
    }
    
    public String[] getCompoundText() {
    	String[] result = this.compoundTextArea.getText().split("\\s*,\\s*");
    	if (result != null && result.length == 1 && result[0].equals("")) {
    		result = null;
    	}
    	return result;
    }
    
    public Color getLowColor() {
    	return this.heatMapLowColor;
    }
    
    public Color getHighColor() {
    	return this.heatMapHighColor;
    }
    
	private void loadProperties() {
    	final Properties prop = new Properties();
    	InputStream input = null;
    	InputStream colorInput = null;    
    	try {    
    		input = new FileInputStream("gui.properties");
    		colorInput = new FileInputStream("color.properties");
    		//load gui properties
    		prop.load(input);
    		this.defaultQueryCompounds = prop.getProperty("default_query_compounds");
    		this.defaultQueryProteins = prop.getProperty("default_query_proteins");
    		this.defaultNumClusters = prop.getProperty("default_num_clusters");
    		this.defaultNumIterations = prop.getProperty("default_num_iterations");
    		
    		//load high/low colors
    		prop.load(colorInput);
    		this.heatMapLowColor = new Color(Integer.parseInt(prop.getProperty("color.low"), 16));
    		this.heatMapHighColor = new Color(Integer.parseInt(prop.getProperty("color.high"), 16));
    	} catch (IOException ex) {
    		ex.printStackTrace();
    	} finally {
    		if (input != null) {
    			try {
    				input.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		if (colorInput != null) {
    			try {
    				colorInput.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
	}
	
	private class ClusteringHandler extends SwingWorker<String, Object> {
		long startTime;
		
		@Override
		public String doInBackground() {
			KMeans kMeansPro = null;
			KMeans kMeansComp = null;
	    	startTime = System.nanoTime();
			if (kMeansCheckBoxes.get(CHECKBOX_PRO).isSelected()) {
				final int numClusters = Integer.parseInt(kMeansTextFields.get(CLUSTER_FIELD_PRO).getText());
				final int numIterations = Integer.parseInt(kMeansTextFields.get(ITERATIONS_FIELD_PRO).getText());
				kMeansPro = new KMeans(numClusters, numIterations);
			}
			if (kMeansCheckBoxes.get(CHECKBOX_COMP).isSelected()) {
				final int numClusters = Integer.parseInt(kMeansTextFields.get(CLUSTER_FIELD_COMP).getText());
				final int numIterations = Integer.parseInt(kMeansTextFields.get(ITERATIONS_FIELD_COMP).getText());
				kMeansComp = new KMeans(numClusters, numIterations);
			}

			controls.generateHeatMap(getCompoundText(), getProteinText(), kMeansPro, kMeansComp);

			return "done";
		}

	       @Override
	       protected void done() {
           	   buttonMap.get(GEN_HEAT_MAP_DATA).setEnabled(true);
	    	   controls.closeProgressBar();
	   			long estimatedTime = System.nanoTime() - startTime;
	   			int seconds = (int) (estimatedTime / 1000000000.0);
	   			logger.info("Heat map data generation complete.");
	   			logger.info("Total time: {} minutes {} seconds\n", (seconds / 60), (seconds % 60));
	       }
	   }
}
